package com.qitianyong.sgkusbcamera;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.UriPermission;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.gkusbsdk.GKUSBCommand;
import com.gkusbsdk.GKUSBFile;
import com.gkusbsdk.GKUSBSDK;

import com.ligo.log.util.ZyLog;
import com.qitianyong.animator.CarAmimator;
import com.qitianyong.decoder.HardDecoder;
import com.qitianyong.decoder.MJpegDecoder;
import com.qitianyong.event.MessageEvent;
import com.qitianyong.extendUI.CircleAdapter;
import com.qitianyong.extendUI.MessageBox;
import com.qitianyong.extendUI.ViewsCircle;
import com.qitianyong.selfclass.BUS_MESSAGE;
import com.qitianyong.selfclass.BaseActivity;
import com.qitianyong.selfclass.CONSTANT;
import com.qitianyong.selfclass.CustomApp;
import com.qitianyong.selfclass.FindDeviceThread;
import com.qitianyong.selfclass.GKDevice;
import com.qitianyong.selfclass.GKResourceID;
import com.qitianyong.selfclass.LogUtils;
import com.qitianyong.selfclass.Message2EventBus;
import com.qitianyong.selfclass.PublicMethod;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import static android.content.DialogInterface.BUTTON_POSITIVE;
import static com.qitianyong.selfclass.GKResourceID.BTN_EXIT;
import static com.qitianyong.selfclass.GKResourceID.BTN_GALLERY;
import static com.qitianyong.selfclass.GKResourceID.BTN_RECORDING;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;


public class PreviewActivity extends BaseActivity implements GKUSBSDK.CallBack, SurfaceHolder.Callback, MessageBox.onEvent {

    // 常量
    private static final int MAX_VIEW_COUNT = 5; // 一屏幕显示最大的View个数
    private static final int MAG_UPDATE_LOCALTIME = 0;
    private static final int MAG_AUTO_HIDE_TOOLBAR = 1;
    private static final int MSG_EXIT_APP = 2;
    private static final int MAX_GET_SD_PROGRESS_SAME_COUNT = 100;
    private static final int REQUEST_PERMISSION_CODE = 1001;

    // UI
    private ImageView __iv_buffer;
    private RelativeLayout __rl_buffer;
    private ViewsCircle __views_circle;
    private CircleAdapter __circleAdapter;
    private SurfaceView __surfaceView;
    private SurfaceHolder __sv_hodler;
    private View __ib_lockrecord;
    private TextView __tv_currenttime;
    private ImageView __iv_defaultbg;
    private ImageView __icon_sdcard;
    private ImageView __icon_audio;
    private TextView __icon_sdcard_no_space;
    private Button __icon_record;
    private ImageView __img_record;
    private ImageView __iv_lock_animate;
    private TextView __tv_lock_percent;
    private RelativeLayout __rl_locking;
    private RelativeLayout __rl_overlay;
    private ImageView __iv_loading;
    private TextView __tv_text;
    private DialogInterface __dialog;

    // 逻辑变量
    private int __toolbarVisible = View.VISIBLE;
    public boolean __bTFCardExsit = false;
    private HardDecoder __decorder;
    private MJpegDecoder __mjpegDecoder;
    private int __recordstatus_bak = GKUSBCommand.STATUS_RECORD.RECORD_UNKNOWN;
    private int __getLockErrCount = 20;
    private int __getSdProgressSameCount = MAX_GET_SD_PROGRESS_SAME_COUNT;
    private int __curSDFormatProgress = 0;

    protected static int created = 0;

    private Handler __handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case MAG_UPDATE_LOCALTIME: {
                    __tv_currenttime.setText(PublicMethod.getCurrentTime());
                    break;
                }
                case MAG_AUTO_HIDE_TOOLBAR: {
                    __toolbarVisible = View.INVISIBLE;
                    ((View) __views_circle.getParent()).setVisibility(__toolbarVisible);
                    break;
                }
                case MSG_EXIT_APP: {
                    GKDevice.getInstance().Destroy();
                    __dialog.dismiss();
                    finish();
                    break;
                }
                default:
                    break;
            }
        }
    };

    @Override
    protected void onDestroy() {
//        LogcatViewer.closeLogcatLoggerView(this);
        super.onDestroy();
        created--;
        showFlashRecordHintThread.interrupt();
    }


    private List<Button> __btnList = new ArrayList<>();
    private int[] __imageid = new int[]{
            R.drawable.btn_exit_default_s,
//            R.drawable.btn_voice_default_s,
            R.drawable.btn_photo_default_s,
            R.drawable.btn_video_default_s,
            R.drawable.btn_folder_default_s,
            R.drawable.btn_formating_default_s,
            R.drawable.btn_reset_s,
            R.drawable.btn_set_default_s
    };

    private int[] __textid = new int[]{
            R.string.text_exit,
//            R.string.text_audio,
            R.string.text_photo,
            R.string.text_record,
            R.string.text_folder,
            R.string.text_format,
            R.string.text_defaultfactory,
            R.string.text_set
    };
    private int exit_filelist_times;

    Thread showFlashRecordHintThread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (!showFlashRecordHintThread.isInterrupted()) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (TextUtils.equals(__icon_record.getText(), getString(R.string.text_recording))) {
                            if (__img_record.getVisibility() == View.VISIBLE) {
                                __img_record.setVisibility(View.INVISIBLE);
                            } else {
                                __img_record.setVisibility(View.VISIBLE);
                            }

                        } else {
                            __img_record.setImageResource(R.drawable.icon_no_record);
                            __img_record.setVisibility(View.VISIBLE);
                        }
                    }
                });

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }

            }
        }
    });


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
        switch (event.code) {
            case MessageEvent.REQUEST_PERMISSION:
                requestPermission();
                break;
            default:
                break;
        }
//        Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        created++;
        if (created > 1) {
            finish();
            return;
        }
        setContentView(R.layout.activity_preview);
        findView();
        setListener();

        initView();
//        LogcatViewer.showLogcatLoggerView(this);

        CarAmimator.startBufferAnimator(4, "frame_", this, __iv_buffer, 50);
        CarAmimator.startBufferAnimator(4, "wheel0", this, __iv_loading, 50);
//        startService(new Intent(this, DaemonService.class));

        GKDevice.getInstance().setCallback(this);
        GKDevice.getInstance().openStream();
//        if (System.currentTimeMillis() > 1701273600000L) {
//            MessageBox.showExDefaultMsgBox(PreviewActivity.this, PreviewActivity.this,
//                    "请更新APP 否则无法使用", CONSTANT.BOX_TYPE.BOX_EXITAPP);
//        }
        FindDeviceThread.getInstance().setIntent(FindDeviceThread.OPEN_APP);
//        tryGetUsbPermission();
        ZyLog.d("onCreate....");
        showFlashRecordHintThread.start();
        playThread.start();
        requestPermission();
//        requestUsbPermission();
    }

    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    private final BroadcastReceiver mUsbPermissionActionReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        //user choose YES for your previously popup window asking for grant perssion for this usb device
                        if (null != usbDevice) {

                        }
                    } else {
                        //user choose NO for your previously popup window asking for grant perssion for this usb device
                        Toast.makeText(context, String.valueOf("Permission denied for device" + usbDevice), Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    };

    private void requestUsbPermission() {
        UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> usbDeviceHashMap = usbManager.getDeviceList();
        for (UsbDevice usbDevice : usbDeviceHashMap.values()) {
            Log.d("gkdevice", usbDevice.getDeviceName() + " " +
                    " permission is " + usbManager.hasPermission(usbDevice));
            if (!usbManager.hasPermission(usbDevice)) {
                IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
                registerReceiver(mUsbPermissionActionReceiver, filter);
                PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
                usbManager.requestPermission(usbDevice, mPermissionIntent);
            }

        }
    }

    private static final String HASPERMISSION = "HASPERMISSION";


    private void requestPermission() {
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//                if (!Environment.isExternalStorageManager()) {
//                    Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
//                    startActivity(intent);
//                } else {
//
//                }
//            }
//        } else

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
            ) {
                ActivityCompat.requestPermissions(this, new String[]{
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE);
            } else {
            }
        } else {
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_PERMISSION_CODE) {
//            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//                // 权限已授予，可以访问外部存储
//                // 在这里进行外部存储的操作
//            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_PERMISSION_CODE && resultCode == RESULT_OK) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                Uri treeUri = data.getData();
                getContentResolver().takePersistableUriPermission(treeUri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION |
                                Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

                SharedPreferences preferences = CustomApp.customApp.getSharedPreferences("config", 0);
                preferences.edit().putBoolean(HASPERMISSION, true).apply();
            }
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
//        tryGetUsbPermission();
//        FindDeviceThread.getInstance().setIntent(FindDeviceThread.OPEN_APP);
//        GKDevice.getInstance().openStream();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("__iv_defaultbg", __iv_defaultbg.getVisibility());
        outState.putInt("__rl_buffer", __rl_buffer.getVisibility());
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        if (GKDevice.__hDevice != 0) {
            __iv_defaultbg.setVisibility(savedInstanceState.getInt("__iv_defaultbg", View.VISIBLE));
            __rl_buffer.setVisibility(savedInstanceState.getInt("__rl_buffer", View.VISIBLE));
        }
    }

    private void findView() {

        __iv_buffer = (ImageView) findViewById(R.id.iv_buffer);
        __views_circle = (ViewsCircle) findViewById(R.id.views_circle);
        __surfaceView = (SurfaceView) findViewById(R.id.sv_livestream);
        __ib_lockrecord = findViewById(R.id.ib_lockrecord);
        __tv_currenttime = (TextView) findViewById(R.id.tv_currenttime);
        __iv_defaultbg = (ImageView) findViewById(R.id.iv_defaultbg);
        __rl_buffer = (RelativeLayout) findViewById(R.id.rl_buffer);
        __icon_sdcard = (ImageView) findViewById(R.id.icon_sdcard);
        __icon_audio = (ImageView) findViewById(R.id.icon_audio);
        __icon_sdcard_no_space = (TextView) findViewById(R.id.icon_sdcard_no_space);
        __icon_record = (Button) findViewById(R.id.icon_record);
        __img_record = (ImageView) findViewById(R.id.img_record);
        __iv_lock_animate = (ImageView) findViewById(R.id.iv_lock_animate);
        __tv_lock_percent = (TextView) findViewById(R.id.tv_lock_percent);
        __rl_locking = (RelativeLayout) findViewById(R.id.rl_locking);
        __rl_overlay = (RelativeLayout) findViewById(R.id.rl_overlay);
        __iv_loading = (ImageView) findViewById(R.id.iv_loading);
        __tv_text = (TextView) findViewById(R.id.tv_text);
    }

    private void setListener() {

        __surfaceView.setOnClickListener(mListener);
        __ib_lockrecord.setOnClickListener(mListener);
        __tv_currenttime.setVisibility(View.INVISIBLE);
        findViewById(R.id.ib_switch_camera).setOnClickListener(mListener);
    }

    private void initView() {

        // 获取屏幕宽度
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        int screen_w = outMetrics.widthPixels;

        Configuration config = getResources().getConfiguration();
        int smallestScreenWidth = config.smallestScreenWidthDp;

      /*  Toast.makeText(this,"small:"+smallestScreenWidth+"width:"+screen_w+" height:"+outMetrics.heightPixels+"density:"+outMetrics.densityDpi,
                Toast.LENGTH_SHORT).show();*/

        // 添加到 ViewPager
        for (int i = 0; i < __imageid.length; i++) {

            Button btn = new Button(this);
            btn.setBackground(null);
            btn.setText(getString(__textid[i]));
            btn.setTextColor(getResources().getColorStateList(R.color.text_normal_s));
            btn.setTextSize(getResources().getDimension(R.dimen.size_small));
            btn.setCompoundDrawablesWithIntrinsicBounds(0, __imageid[i], 0, 0);
            btn.setId(GKResourceID.BTN_EXIT + i);
            btn.setOnClickListener(mListener);
            btn.setWidth(screen_w / MAX_VIEW_COUNT);

            __btnList.add(btn);
        }

        __circleAdapter = new CircleAdapter(__btnList);
        __views_circle.setAdapter(__circleAdapter);
        __views_circle.setScreen(screen_w);

        __sv_hodler = __surfaceView.getHolder();
        __sv_hodler.addCallback(this);
    }

    private View.OnClickListener mListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            LogUtils.addClickLog(v.getId());
            switch (v.getId()) {
             /*   case GKResourceID.BTN_AUDIO:{
                    messsageBox(getString(R.string.tip_nosupport));
                    break;
                }*/
                case GKResourceID.BTN_FORMAT: {
                    if (!__bTFCardExsit) {
                        messsageBox(getString(R.string.tip_tfcard_notexsit));
                        break;
                    }

                    MessageBox.showExDefaultMsgBox(PreviewActivity.this, PreviewActivity.this,
                            getString(R.string.tip_format), CONSTANT.BOX_TYPE.BOX_SDFORMAT);
                    break;
                }
                case GKResourceID.BTN_FACTORY: {
                    MessageBox.showExDefaultMsgBox(PreviewActivity.this, PreviewActivity.this,
                            getString(R.string.tip_default), CONSTANT.BOX_TYPE.BOX_DEFAULTFACTORY);
                    break;
                }
                case GKResourceID.BTN_EXIT: {
                    MessageBox.showExDefaultMsgBox(PreviewActivity.this, PreviewActivity.this,
                            getString(R.string.tip_exit), CONSTANT.BOX_TYPE.BOX_EXITAPP);
                    break;
                }
                case BTN_GALLERY: {

                    int i = GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_ENTER_FILELIST, null);
                    __btnList.get(BTN_GALLERY - BTN_EXIT).setClickable(i == -1);
                    break;
                }
                case GKResourceID.BTN_RECORDING: {
                    GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_SETRECORD_STATUS, null);
                    break;
                }
                case GKResourceID.BTN_SETTING: {

                    Intent inConfig = new Intent(PreviewActivity.this, ConfigActivity.class);
                    startActivity(inConfig);
                    break;
                }
                case GKResourceID.BTN_SHOT: {
                    if (!__bTFCardExsit) {
                        messsageBox(getString(R.string.tip_tfcard_notshot));
                        break;
                    }
                    if (__icon_sdcard_no_space.getVisibility() == View.VISIBLE) {
                        messsageBox(getString(R.string.sd_no_space_hint));
                        break;
                    }
                    GKUSBFile usbFile = new GKUSBFile();
                    usbFile.__lock = GKUSBCommand.FILE_TYPE.PHOTO_FILE;
                    usbFile.__command = GKUSBCommand.PHOTO_FILE_CONTROL.CONTROL_CAPTURE;

                    int ret = GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_FILE_CONTROL, usbFile);
                    if (ret != -1) {
                        __tv_text.setText(getString(R.string.shoting));
                        __rl_overlay.setVisibility(View.VISIBLE);
                    }
                    break;
                }
                case R.id.sv_livestream: {
                    if (__toolbarVisible == View.VISIBLE) {
                        __toolbarVisible = View.GONE;
                    } else {
                        __toolbarVisible = View.VISIBLE;
                    }

                    ((View) __views_circle.getParent()).setVisibility(__toolbarVisible);
                    if (__rl_locking.getVisibility() != View.VISIBLE) {
                        __ib_lockrecord.setVisibility(__toolbarVisible);
                    }

                    break;
                }
                case R.id.ib_lockrecord: {
                    if (!__bTFCardExsit) {
                        messsageBox(getString(R.string.tip_tfcard_notlock));
                        break;
                    }
                    if (__icon_sdcard_no_space.getVisibility() == View.VISIBLE) {
                        messsageBox(getString(R.string.sd_no_space_hint));
                        break;
                    }
                    __ib_lockrecord.setEnabled(false);
                    GKUSBFile usbFile = new GKUSBFile();
                    usbFile.__lock = GKUSBCommand.FILE_TYPE.HURRY_FILE;
                    usbFile.__command = GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_CAPTURE2LOCK;

                    GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_FILE_CONTROL, usbFile);
                    break;
                }
                case R.id.ib_switch_camera:
                    try {
                        GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_SWITCH_CAMERA, 0);
//                        int checkCameraId = GKUSBSDK.GKUSB_GetLiveScreenStatus(GKDevice.__hDevice);
//                        String[] items = new String[]{"第一路", "第二路", "第三路", "第四路"};
//                        AlertDialog.Builder builder = new AlertDialog.Builder(PreviewActivity.this);
//                        builder.setSingleChoiceItems(items, checkCameraId, new DialogInterface.OnClickListener() {
//                            @Override
//                            public void onClick(DialogInterface dialogInterface, int i) {
//                                GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_SWITCH_CAMERA, i);
//                                dialogInterface.dismiss();
//                            }
//                        });
//                        builder.create().show();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    public void onBackPressed() {
        MessageBox.showExDefaultMsgBox(PreviewActivity.this, PreviewActivity.this,
                getString(R.string.tip_exit), CONSTANT.BOX_TYPE.BOX_EXITAPP);
    }

    public LinkedList<byte[]> videoDatas = new LinkedList<>();

    public long lastDecodeTime;
    Thread playThread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (!PreviewActivity.this.isFinishing()) {
                long l = System.currentTimeMillis() - lastDecodeTime;
                int sleep = 20 - l > 0 ? (int) (20 - l) : 0;
                try {
                    Thread.sleep(sleep);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                while (true) {
                    byte[] data;
                    synchronized (videoDatas) {
                        if (videoDatas.isEmpty()) {
                            break;
                        }
                        data = videoDatas.getFirst();
                        videoDatas.removeFirst();
                    }
                    if (data != null) {
//                        if (__decorder != null) {
//                            __decorder.Decoder(data, data.length);
//                            lastDecodeTime = System.currentTimeMillis();
//                        }

                        if (__mjpegDecoder != null) {
                            long startTime = System.currentTimeMillis();
                            __mjpegDecoder.decodeFrame(data);
                            Log.i("decodeFrame", "decodeFrame time:" + (System.currentTimeMillis() - startTime));
                            lastDecodeTime = System.currentTimeMillis();
                        }
                    }
                    synchronized (videoDatas) {
                        if (videoDatas.size() <= 1) {
                            break;
                        }
                    }
                }


            }

        }
    });
    public static long lastPreviewActivityUpdateTime = System.currentTimeMillis();

    @Override
    public void cb_stream(long hUSBDevice, byte[] data, int length, int width, int height, int time) {
//        Log.i("stream", ""+data[0]+" "+data[1]+" "+data[2]+" "+data[3]+" "+data[4]+" length:"+length);
        lastPreviewActivityUpdateTime = System.currentTimeMillis();

        synchronized (videoDatas) {
            videoDatas.addLast(data);
        }

    }

    @Override
    public void surfaceCreated(final SurfaceHolder holder) {
        __handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (holder.getSurface().isValid()) {
//                    __decorder = new HardDecoder(CONSTANT.MAX_WIDTH,
//                            CONSTANT.MAX_HEIGHT, holder.getSurface());
                    __mjpegDecoder = new MJpegDecoder(holder.getSurface(), __surfaceView.getWidth(), __surfaceView.getHeight());

                }
            }
        }, 450);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
//        if (__decorder != null)
//            __decorder.Destroy();
        if (__mjpegDecoder != null) {
            __mjpegDecoder.release();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(Message2EventBus message) {

        switch (message.__what) {
            case BUS_MESSAGE.BUS_OPENSTREAM_OK: {

                __rl_buffer.setVisibility(View.INVISIBLE);
                __iv_defaultbg.setVisibility(View.INVISIBLE);
                break;
            }
            case BUS_MESSAGE.BUS_OFFLINE: {

                __rl_buffer.setVisibility(View.VISIBLE);
                __iv_defaultbg.setVisibility(View.VISIBLE);

                // 掉线清理
                __icon_sdcard.setImageResource(R.drawable.icon_def_sd_card_out);
                __bTFCardExsit = false;
                __icon_sdcard_no_space.setVisibility(View.INVISIBLE);

                __icon_audio.setImageResource(R.drawable.icon_out_auido);
                __img_record.setImageResource(R.drawable.icon_no_record);
                __img_record.setVisibility(View.VISIBLE);
                __icon_record.setText(getString(R.string.text_norecord));
                __recordstatus_bak = GKUSBCommand.STATUS_RECORD.RECORD_UNKNOWN;

                break;
            }
            case BUS_MESSAGE.BUS_ENTER_FILELIST: {

                if (((int) message.object) != -1) { // 进入成功，打开图库
                    Intent inGallery = new Intent(PreviewActivity.this, GalleryActivity.class);
                    inGallery.putExtra("status", __recordstatus_bak);
                    startActivity(inGallery);
                }
                __btnList.get(BTN_GALLERY - BTN_EXIT).post(new Runnable() {
                    @Override
                    public void run() {
                        __btnList.get(BTN_GALLERY - BTN_EXIT).setClickable(true);
                    }
                });
                break;
            }
            case BUS_MESSAGE.BUS_EXIT_FILELIST: {
                //执行 EXIT_FILELIST 失败 10 次后不再执行
                if (((int) message.object) == -1 && exit_filelist_times < 10) {
                    exit_filelist_times++;
                    GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_EXIT_FILELIST, null);
                } else {
                    exit_filelist_times = 0;
                }
                break;
            }
            case BUS_MESSAGE.BUS_SDCARD_EXSIT: {

                int status = (int) message.object;
                if (status == GKUSBCommand.RESULT_SDCARD_EXSIT.EXSIT) {
                    __icon_sdcard.setImageResource(R.drawable.icon_def_sd_card);
                    __bTFCardExsit = true;
                } else {
                    __icon_sdcard.setImageResource(R.drawable.icon_def_sd_card_out);
                    __bTFCardExsit = false;
                }
                break;
            }
            case BUS_MESSAGE.BUS_GET_RECORD_AUDIO_PREVIEW: {
                int result = (int) message.object;
                if (result == GKUSBCommand.SWITCH.OPEN) {
                    __icon_audio.setImageResource(R.drawable.icon_def_auido);
                } else {
                    __icon_audio.setImageResource(R.drawable.icon_out_auido);
                }
                break;
            }
            case BUS_MESSAGE.BUS_GET_SDCARD_FORMAT: {

                int status = (int) message.object;
                if (status == -1 || status == 255 || __getSdProgressSameCount == 0) {
                    messsageBox(getString(R.string.tip_format_err));
                    __rl_overlay.setVisibility(View.INVISIBLE);
                    __tv_text.setText(getString(R.string.wait));
                } else if (status == 100) {

                    messsageBox(getString(R.string.tip_format_ok));
                    __rl_overlay.setVisibility(View.INVISIBLE);
                    __tv_text.setText(getString(R.string.wait));
                } else {
                    if (__curSDFormatProgress != status) {

                        __curSDFormatProgress = status;
                        __getSdProgressSameCount = MAX_GET_SD_PROGRESS_SAME_COUNT;
                        Log.i("format", "curSDFormatProgress reset:" + status);
                    } else {
                        __getSdProgressSameCount--; // 20次格式化一直为同一个值
                        Log.i("format", "curSDFormatProgress-1:" + __getSdProgressSameCount);
                    }

                    GKDevice.getInstance().sendCommand(
                            CONSTANT.COMMAND.CMD_GET_SDCARD_FORMAT, null);
                    __tv_text.setText(getString(R.string.formating) + " " + status + "%");
                }
                break;
            }
            case BUS_MESSAGE.BUS_GETRECORD_STATUS: {

                int status = (int) message.object;

                if (status == GKUSBCommand.STATUS_RECORD.RECORDING
                        || status == GKUSBCommand.STATUS_RECORD.NORECORD_EXSIT_SD
                        || status == GKUSBCommand.STATUS_RECORD.NORECORD_EXSIT_SD_NO_SPACE) {
                    __icon_sdcard.setImageResource(R.drawable.icon_def_sd_card);
                    __bTFCardExsit = true;
                } else {
                    __icon_sdcard.setImageResource(R.drawable.icon_def_sd_card_out);
                    __bTFCardExsit = false;
                }
                if (status == GKUSBCommand.STATUS_RECORD.NORECORD_EXSIT_SD_NO_SPACE) {
                    __icon_sdcard_no_space.setVisibility(View.VISIBLE);
                } else {
                    __icon_sdcard_no_space.setVisibility(View.INVISIBLE);
                }
                if (status == GKUSBCommand.STATUS_RECORD.RECORDING) {
                    __img_record.setImageResource(R.drawable.icon_no_record);
                    __btnList.get(BTN_RECORDING - BTN_EXIT).setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_video_default_s, 0, 0);
                    __btnList.get(BTN_RECORDING - BTN_EXIT).setTextColor(getResources().getColorStateList(R.color.text_normal_s));

                    __icon_record.setText(getString(R.string.text_recording));

                    if (__recordstatus_bak != status &&
                            __recordstatus_bak != GKUSBCommand.STATUS_RECORD.RECORD_UNKNOWN) {
                        messsageBox(getString(R.string.tip_open_record_success));
                    }
                } else {
                    __btnList.get(BTN_RECORDING - BTN_EXIT).setTextColor(getResources().getColorStateList(R.color.text_gray_s));
                    __btnList.get(BTN_RECORDING - BTN_EXIT).setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_video_stop_s, 0, 0);
                    __img_record.setImageResource(R.drawable.icon_no_record);
                    __img_record.setVisibility(View.VISIBLE);
                    __icon_record.setText(getString(R.string.text_norecord));
                    if (__recordstatus_bak != status &&
                            __recordstatus_bak == GKUSBCommand.STATUS_RECORD.RECORDING &&
                            (status == GKUSBCommand.STATUS_RECORD.NORECORD_EXSIT_SD
                                    || status == GKUSBCommand.STATUS_RECORD.NORECORD_NO_EXSIT_SD
                                    || status == GKUSBCommand.STATUS_RECORD.NORECORD_EXSIT_SD_NO_SPACE)) {
                        messsageBox(getString(R.string.tip_close_record_success));
                    }
                }
                __recordstatus_bak = status;
                break;
            }
            case BUS_MESSAGE.BUS_SET_SDCARD_FORMAT: {
                int status = (int) message.object;
                if (status != -1) { // 格式化指令发送成功
                    // 开线程检测SD卡格式化进度
                    GKDevice.getInstance().sendCommand(
                            CONSTANT.COMMAND.CMD_GET_SDCARD_FORMAT, null);
                } else {
                    messsageBox(getString(R.string.tip_format_err));
                    __rl_overlay.setVisibility(View.INVISIBLE);
                    __tv_text.setText(getString(R.string.wait));
                }
                break;
            }
            case BUS_MESSAGE.BUS_SETRECORD_STATUS: {

                break;
            }
            case BUS_MESSAGE.BUS_CONTROL_ERR: {
                GKUSBFile usbFile = (GKUSBFile) message.object;
                if (usbFile.__lock == GKUSBCommand.FILE_TYPE.PHOTO_FILE) {
                    switch (usbFile.__command) {
                        case GKUSBCommand.PHOTO_FILE_CONTROL.CONTROL_CAPTURE: {
                            messsageBox(getString(R.string.tip_capture_err));
                            __rl_overlay.setVisibility(View.INVISIBLE);
                            break;
                        }
                        default:
                            break;
                    }
                } else {
                    switch (usbFile.__command) {
                        case GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_CAPTURE2LOCK: {
                            messsageBox(getString(R.string.lock_record_err));
                            __ib_lockrecord.setEnabled(true);
                            break;
                        }
                        default:
                            break;
                    }

                }
                break;
            }
            case BUS_MESSAGE.BUS_CONTROL_OK: {
                GKUSBFile usbFile = (GKUSBFile) message.object;
                if (usbFile.__lock == GKUSBCommand.FILE_TYPE.PHOTO_FILE) {
                    switch (usbFile.__command) {
                        case GKUSBCommand.PHOTO_FILE_CONTROL.CONTROL_CAPTURE: {

                            __rl_overlay.setVisibility(View.INVISIBLE);
                            __tv_text.setText(getString(R.string.wait));
                            messsageBox(getString(R.string.tip_capture_ok));
                            break;
                        }
                        default:
                            break;
                    }
                } else {
                    switch (usbFile.__command) {
                        case GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_CAPTURE2LOCK: {
                            __rl_locking.setVisibility(View.VISIBLE);

                            CarAmimator.startBufferAnimator(9, "circle",
                                    PreviewActivity.this, __iv_lock_animate, 100);
                            __ib_lockrecord.setVisibility(View.INVISIBLE);
                            __ib_lockrecord.setEnabled(true);
                            __getLockErrCount = 20;// 预备为3次获取进度失败
                            GKDevice.getInstance().sendCommand(
                                    CONSTANT.COMMAND.CMD_GETLOCK_PROGRESS, null);
                            break;
                        }
                        default:
                            break;
                    }
                }
                break;
            }
            case BUS_MESSAGE.BUS_DEFAULT_FACTORY: {
                int status = (int) message.object;
                if (status == -1) {
                    messsageBox(getString(R.string.tip_defaultfactory_err));
                } else {
                    messsageBox(getString(R.string.tip_defaultfactory_ok));
                }
                break;
            }
            case BUS_MESSAGE.BUS_PRINT: {
                __rl_locking.setVisibility(View.INVISIBLE);
                CarAmimator.stopBufferAnimator(__iv_lock_animate);

                if (__views_circle.getVisibility() == View.VISIBLE) {
                    __ib_lockrecord.setVisibility(View.VISIBLE);
                }
                messsageBox(getString(R.string.tip_device_disnn));
                break;
            }
            case BUS_MESSAGE.BUS_RECORD_HURRY: {

                int status = (int) message.object;
                if (status == 1 || __getLockErrCount == 0) {

                    if (__getLockErrCount == 0) {
                        messsageBox(getString(R.string.lock_record_err));
                        Log.i("lock", "----------lock record err--------");
                    } else {
                        messsageBox(getString(R.string.lock_record_ok));
                        Log.i("lock", "----------lock record ok--------");
                    }

                    __rl_locking.setVisibility(View.INVISIBLE);
                    CarAmimator.stopBufferAnimator(__iv_lock_animate);

                    if (__views_circle.getVisibility() == View.VISIBLE) {
                        __ib_lockrecord.setVisibility(View.VISIBLE);
                    }
                } else {
                    if (status == -1) {
                        __getLockErrCount--;
                        Log.i("lock", "----------(getLockErrCount--)--------");
                    } else
                        Log.i("lock", "----------status:" + status);
                    GKDevice.getInstance().sendCommand(
                            CONSTANT.COMMAND.CMD_GETLOCK_PROGRESS, null);
                }

                break;
            }
            default:
                break;
        }
    }

    @Override
    public void onAlertClick(DialogInterface dialog, int id, int flag, MessageBox msgBox) {

        if (id == BUTTON_POSITIVE) {

            if (flag == CONSTANT.BOX_TYPE.BOX_EXITAPP) {

                CarAmimator.stopBufferAnimator(__iv_buffer);
                CarAmimator.stopBufferAnimator(__iv_loading);

                msgBox.setBufferVisible(View.VISIBLE, getString(R.string.tip_app_exiting));
                __dialog = dialog;
                __handler.sendEmptyMessage(MSG_EXIT_APP);

            } else if (flag == CONSTANT.BOX_TYPE.BOX_SDFORMAT) {

                int ret = GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_SET_SDCARD_FORMAT, null);
                if (ret != -1) {
                    __rl_overlay.setVisibility(View.VISIBLE);
                    __getSdProgressSameCount = MAX_GET_SD_PROGRESS_SAME_COUNT;
                    __curSDFormatProgress = 0;
                }

                dialog.dismiss();
            } else if (flag == CONSTANT.BOX_TYPE.BOX_DEFAULTFACTORY) {
                GKDevice.getInstance().sendCommand(CONSTANT.COMMAND.CMD_DEFAULT_FACTORY, null);
                dialog.dismiss();
            }
        } else {
            dialog.dismiss();
        }
    }

    private void messsageBox(String message) {
        if (isFinishing() || isDestroyed()) {
            return;
        }
        if (__toast != null) {
            __toast.cancel();
        }

        __toast = Toast.makeText(PreviewActivity.this, message, Toast.LENGTH_SHORT);
        __toast.setGravity(Gravity.CENTER, 0, 0);
        View __toastView = __toast.getView();
        if (__toastView != null &&
                __toastView instanceof ViewGroup &&
                ((ViewGroup) __toastView).getChildCount() == 1 &&
                ((ViewGroup) __toastView).getChildAt(0) instanceof TextView)
            ((TextView) ((ViewGroup) __toastView).getChildAt(0)).setTextSize(TypedValue.COMPLEX_UNIT_PX, (int) getResources().getDimension(R.dimen.main_page_toast_text_size));
        __toast.show();
    }

    @Override
    protected void onResume() {
        super.onResume();
        lastPreviewActivityUpdateTime = System.currentTimeMillis();
        GKDevice.getInstance().setCallback(this);

        new Thread(new Runnable() {
            @Override
            public void run() {
                final SharedPreferences once = getSharedPreferences("once", 0);
                boolean aBoolean = once.getBoolean("firstHint", false);
                if (!aBoolean) {
                    int hintStringRes = R.string.restart_dvr_hint;
                    if (Build.MODEL.toLowerCase().contains("sofia")) {
                        List<PackageInfo> installedPackages = getPackageManager().getInstalledPackages(0);
                        for (PackageInfo installedPackage : installedPackages) {
                            if (TextUtils.equals(installedPackage.packageName, "com.syu.dvr")) {
//                                TempReplace.main(PreviewActivity.this);
                                hintStringRes = R.string.restart_dvr_reboot_hint;
                                break;
                            }
                        }
                    } else if (Build.MODEL.toLowerCase().contains("k1s") && Build.MODEL.toLowerCase().contains("aml")) {
                        hintStringRes = R.string.restart_dvr_reboot_hint;
//                        TempReplace.main(PreviewActivity.this);
                    }
                    final int finalHintStringRes = hintStringRes;
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println(Thread.currentThread().getName());
                            MessageBox.ShowConfirmMessageBox(PreviewActivity.this, new MessageBox.onEvent() {
                                @Override
                                public void onAlertClick(DialogInterface dialog, int id, int flag, MessageBox msgBox) {
                                    dialog.dismiss();
                                }
                            }, getString(finalHintStringRes));

                        }
                    });
                    once.edit().putBoolean("firstHint", true).apply();
                }
            }
        }).start();
    }


}
